home *** CD-ROM | disk | FTP | other *** search
/ mail.altrad.com / 2015.02.mail.altrad.com.tar / mail.altrad.com / TEST / office german / PROPLUS.WW / PROPLSWW.CAB / XML2WORD.XSL < prev    next >
Extensible Markup Language  |  2004-05-18  |  10KB  |  283 lines

  1. ∩╗┐<?xml version="1.0" encoding="UTF-8" ?>
  2. <xsl:stylesheet 
  3.     version="1.0"
  4.     xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" 
  5.     xmlns:v="urn:schemas-microsoft-com:vml" 
  6.     xmlns:w10="urn:schemas-microsoft-com:office:word" 
  7.     xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" 
  8.     xmlns:aml="http://schemas.microsoft.com/aml/2001/core" 
  9.     xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" 
  10.     xmlns:o="urn:schemas-microsoft-com:office:office" 
  11.     xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
  12.     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  13.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  14.     exclude-result-prefixes="xsi">
  15.     <xsl:variable name="dxaIndent" select="'360'" />
  16.     <xsl:template match="/">
  17.         <xsl:processing-instruction name="mso-application">progid="Word.Document"</xsl:processing-instruction>
  18.         <xsl:variable name="currentSpacePreserve">
  19.             <xsl:value-of select="/*/@xml:space"/>
  20.         </xsl:variable>
  21.         <w:wordDocument>
  22.                     <xsl:if test="$currentSpacePreserve != ''">
  23.                         <xsl:attribute name="xml:space">
  24.                             <xsl:value-of select="$currentSpacePreserve"/>
  25.                         </xsl:attribute>
  26.                     </xsl:if>
  27.             <!-- save processing instructions as custom document properties in order to preserve them on save -->
  28.             <xsl:if test="processing-instruction()">
  29.                 <o:CustomDocumentProperties>
  30.                     <xsl:element name="o:processingInstructions">
  31.                         <xsl:attribute name="dt:dt">string</xsl:attribute>
  32.                         <xsl:apply-templates select="processing-instruction()" mode="piMode" />
  33.                     </xsl:element>
  34.                 </o:CustomDocumentProperties>
  35.             </xsl:if>
  36.             <!-- check for schemaLocation attributes in the file - if they exist, convert them to schema library entries (so we can attach them if possible) -->
  37.             <xsl:if test="//@xsi:schemaLocation">
  38.                 <sl:schemaLibrary>
  39.                     <xsl:for-each select="//@xsi:schemaLocation">
  40.                         <xsl:call-template name="schemaLocationTransform">
  41.                             <xsl:with-param name="schemaLocationString" select="." />
  42.                         </xsl:call-template>
  43.                     </xsl:for-each>
  44.                 </sl:schemaLibrary>
  45.             </xsl:if>
  46.             <!-- set Word document properties for raw XML - save as raw XML and show XML tags in the document -->
  47.             <w:docPr>
  48.                 <w:view w:val="web" />
  49.                 <w:removeWordSchemaOnSave w:val="on" />
  50.                 <w:showXMLTags w:val="on" />
  51.             </w:docPr>
  52.             
  53.             <!-- insert the body tags for the Word document, and begin processing the file's content -->
  54.             <w:body>
  55.                 <xsl:apply-templates>
  56.                     <xsl:with-param name="spacePreserve" select="$currentSpacePreserve"/>
  57.                 </xsl:apply-templates>
  58.             </w:body>
  59.         </w:wordDocument>
  60.     </xsl:template>
  61.     <xsl:template match="*">
  62.         <xsl:param name="spacePreserve" select="default"/>
  63.         <!-- first, set the depth (in twips) for the current indent level -->
  64.         <xsl:variable name="depth">
  65.             <xsl:choose>
  66.                 <xsl:when test="count(ancestor::node()) * $dxaIndent >= 4320">
  67.                     <xsl:value-of select="4320" />
  68.                 </xsl:when>
  69.                 <xsl:otherwise>
  70.                     <xsl:value-of select="$dxaIndent*count(ancestor::node()) - $dxaIndent" />
  71.                 </xsl:otherwise>
  72.             </xsl:choose>
  73.         </xsl:variable>
  74.         <xsl:variable name="currentSpacePreserve">
  75.             <xsl:choose>
  76.                 <xsl:when test="@xml:space">
  77.                     <xsl:value-of select="@xml:space" />
  78.                 </xsl:when>
  79.                 <xsl:otherwise>
  80.                     <xsl:value-of select="$spacePreserve" />
  81.                 </xsl:otherwise>
  82.             </xsl:choose>
  83.         </xsl:variable>
  84.         <xsl:copy>
  85.             <xsl:copy-of select="@*" />
  86.             <xsl:choose>
  87.                 <xsl:when test="count(node())=0">
  88.                     <!-- processing a leaf node with no children -->
  89.                     <w:p>
  90.                         <w:pPr>
  91.                             <w:ind>
  92.                                 <xsl:attribute name="w:left">
  93.                                     <xsl:value-of select="$depth" />
  94.                                 </xsl:attribute>
  95.                             </w:ind>
  96.                         </w:pPr>
  97.                     </w:p>
  98.                 </xsl:when>
  99.                 <xsl:when test="count(node())=1">
  100.                     <!-- processing a node with one child node -->
  101.                     <xsl:choose>
  102.                         <xsl:when test="generate-id(child::node()[1])=generate-id(child::text()[1])">
  103.                             <!-- if the first node is a text node, their id's will be the same, therefore this node has a single child, and it's text -->
  104.                             <xsl:apply-templates mode="leafNode">
  105.                                 <xsl:with-param name="spacePreserve" select="$currentSpacePreserve"/>
  106.                             </xsl:apply-templates>
  107.                         </xsl:when>
  108.                         <xsl:otherwise>
  109.                             <!-- otherwise, this node has a single child, and it's NOT text -->
  110.                             <w:p>
  111.                                 <w:pPr>
  112.                                     <w:ind>
  113.                                         <xsl:attribute name="w:left">
  114.                                             <xsl:value-of select="$depth" />
  115.                                         </xsl:attribute>
  116.                                     </w:ind>
  117.                                 </w:pPr>
  118.                             </w:p>
  119.                             <xsl:apply-templates>
  120.                                 <xsl:with-param name="spacePreserve" select="$currentSpacePreserve"/>
  121.                             </xsl:apply-templates>
  122.                             <w:p>
  123.                                 <w:pPr>
  124.                                     <w:ind>
  125.                                         <xsl:attribute name="w:left">
  126.                                             <xsl:value-of select="$depth" />
  127.                                         </xsl:attribute>
  128.                                     </w:ind>
  129.                                 </w:pPr>
  130.                             </w:p>
  131.                         </xsl:otherwise>
  132.                     </xsl:choose>
  133.                 </xsl:when>
  134.                 <xsl:otherwise>
  135.                     <!-- processing a node with multiple children -->
  136.                     <w:p>
  137.                         <w:pPr>
  138.                             <w:ind>
  139.                                 <xsl:attribute name="w:left">
  140.                                     <xsl:value-of select="$depth" />
  141.                                 </xsl:attribute>
  142.                             </w:ind>
  143.                         </w:pPr>
  144.                     </w:p>
  145.                     <xsl:apply-templates>
  146.                         <xsl:with-param name="spacePreserve" select="$currentSpacePreserve"/>
  147.                     </xsl:apply-templates>
  148.                     <w:p>
  149.                         <w:pPr>
  150.                             <w:ind>
  151.                                 <xsl:attribute name="w:left">
  152.                                     <xsl:value-of select="$depth" />
  153.                                 </xsl:attribute>
  154.                             </w:ind>
  155.                         </w:pPr>
  156.                     </w:p>
  157.                 </xsl:otherwise>
  158.             </xsl:choose>
  159.         </xsl:copy>
  160.     </xsl:template>
  161.     
  162.     <xsl:template match="w:* | v:* | w10:* | sl:* | aml:* | wx:* | o:* | dt:*">
  163.         <xsl:param name="spacePreserve" select="default"/>
  164.         <xsl:variable name="currentSpacePreserve">
  165.             <xsl:choose>
  166.                 <xsl:when test="@xml:space">
  167.                     <xsl:value-of select="@xml:space" />
  168.                 </xsl:when>
  169.                 <xsl:otherwise>
  170.                     <xsl:value-of select="$spacePreserve" />
  171.                 </xsl:otherwise>
  172.             </xsl:choose>
  173.         </xsl:variable>
  174.         <xsl:apply-templates>
  175.             <xsl:with-param name="spacePreserve" select="$currentSpacePreserve"/>
  176.         </xsl:apply-templates>
  177.     </xsl:template>
  178.     
  179.     <xsl:template match="text()">
  180.         <xsl:param name="spacePreserve" select="default"/>
  181.         <!-- first, set the depth (in twips) for the current indent level -->
  182.         <xsl:variable name="depth">
  183.             <xsl:choose>
  184.                 <xsl:when test="count(ancestor::node()) * $dxaIndent >= 4320">
  185.                     <xsl:value-of select="4320" />
  186.                 </xsl:when>
  187.                 <xsl:otherwise>
  188.                     <xsl:value-of select="$dxaIndent*count(ancestor::node())-$dxaIndent" />
  189.                 </xsl:otherwise>
  190.             </xsl:choose>
  191.         </xsl:variable>
  192.         <xsl:variable name="currentSpacePreserve"><xsl:value-of select="$spacePreserve" /></xsl:variable>
  193.         <!-- processing a non-leaf text node, set the indent spacing -->
  194.         <w:p>
  195.             <w:pPr>
  196.                 <w:ind>
  197.                     <xsl:attribute name="w:left">
  198.                         <xsl:value-of select="$depth" />
  199.                     </xsl:attribute>
  200.                 </w:ind>
  201.             </w:pPr>
  202.             <w:r>
  203.                 <w:t>
  204.                     <xsl:if test="$currentSpacePreserve != ''">
  205.                         <xsl:attribute name="xml:space">
  206.                             <xsl:value-of select="$currentSpacePreserve"/>
  207.                         </xsl:attribute>
  208.                     </xsl:if>
  209.                     <xsl:value-of select="." />
  210.                 </w:t>
  211.             </w:r>
  212.         </w:p>
  213.     </xsl:template>
  214.     <xsl:template match="text()" mode="leafNode">
  215.         <xsl:param name="spacePreserve" select="default"/>
  216.         <!-- first, set the depth (in twips) for the current indent level -->
  217.         <xsl:variable name="depth">
  218.             <xsl:choose>
  219.                 <xsl:when test="count(ancestor::node()) * $dxaIndent >= 4320">
  220.                     <xsl:value-of select="4320" />
  221.                 </xsl:when>
  222.                 <xsl:otherwise>
  223.                     <xsl:value-of select="$dxaIndent*count(ancestor::node()) - $dxaIndent * 2" />
  224.                 </xsl:otherwise>
  225.             </xsl:choose>
  226.         </xsl:variable>
  227.         <xsl:variable name="currentSpacePreserve"><xsl:value-of select="$spacePreserve" /></xsl:variable>
  228.         <!-- processing a leaf text node, set the indent spacing to account for the parent tag on the same line -->
  229.         <w:p>
  230.             <w:pPr>
  231.                 <w:ind>
  232.                     <xsl:attribute name="w:left">
  233.                         <xsl:value-of select="$depth" />
  234.                     </xsl:attribute>
  235.                 </w:ind>
  236.             </w:pPr>
  237.             <w:r>
  238.                 <w:t>
  239.                     <xsl:if test="$currentSpacePreserve != ''">
  240.                         <xsl:attribute name="xml:space">
  241.                             <xsl:value-of select="$currentSpacePreserve"/>
  242.                         </xsl:attribute>
  243.                     </xsl:if>
  244.                     <xsl:value-of select="." />
  245.                 </w:t>
  246.             </w:r>
  247.         </w:p>
  248.     </xsl:template>
  249.     <!-- we will copy the contents of PI's into custom document properties exactly as they were -->
  250.     <xsl:template match="processing-instruction()" mode="piMode"><?<xsl:value-of select="local-name()" /> <xsl:value-of select="." />?></xsl:template>
  251.     <!-- We will recursively call this function. It will go through each entry in the xsi:schemaLocation attribute -->
  252.     <xsl:template name="schemaLocationTransform">
  253.         <xsl:param name="schemaLocationString" />
  254.         <xsl:variable name="schemaLocationStringNormalized">
  255.             <xsl:value-of select="normalize-space($schemaLocationString)" />
  256.         </xsl:variable>
  257.         <xsl:variable name="schemaLocationStringAfterURI">
  258.             <xsl:value-of select="substring-after($schemaLocationStringNormalized, ' ')" />
  259.         </xsl:variable>
  260.         <xsl:variable name="schemaLocationStringAfterLocation">
  261.             <xsl:value-of select="substring-after($schemaLocationStringAfterURI, ' ')" />
  262.         </xsl:variable>
  263.         <sl:schema>
  264.             <xsl:attribute name="sl:uri">
  265.                 <xsl:value-of select="substring-before($schemaLocationStringNormalized, ' ')" />
  266.             </xsl:attribute>
  267.             <xsl:attribute name="sl:schemaLocation">
  268.                 <xsl:if test="contains($schemaLocationStringAfterURI, ' ')">
  269.                     <xsl:value-of select="substring-before($schemaLocationStringAfterURI, ' ')" />
  270.                 </xsl:if>
  271.                 <xsl:if test="not(contains($schemaLocationStringAfterURI, ' '))">
  272.                     <xsl:value-of select="$schemaLocationStringAfterURI" />
  273.                 </xsl:if>
  274.             </xsl:attribute>
  275.         </sl:schema>
  276.         <xsl:if test="contains($schemaLocationStringAfterLocation, ' ')">
  277.             <xsl:call-template name="schemaLocationTransform">
  278.                 <xsl:with-param name="schemaLocationString" select="$schemaLocationStringAfterLocation" />
  279.             </xsl:call-template>
  280.         </xsl:if>
  281.     </xsl:template>
  282. </xsl:stylesheet>
  283.